# https://www.frankcleary.com/svdimage/
# https://bigdataschool.ru/blog/recommender-systems-advanced-algorithms.html#:~:text=%D0%A1%D0%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D0%BE%D0%B5%20%D1%80%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%20(SVD%2D%D1%80%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5)%20%E2%80%93,%D0%BC%D0%BE%D0%B3%D0%BB%D0%B8%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%BE%D0%B3%D0%BD%D0%BE%D0%B7%20%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B8%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F

'''
https://www.geeksforgeeks.org/image-reconstruction-using-singular-value-decomposition-svd-in-python/

Хотя 1-й собственный вектор содержит 99,77% информации, реконструкция изображения только по нему не дает четкой картины.
Использование 15 лучших векторов для реконструкции изображения дает достаточно хорошее приближение. Также из 3648 векторов,
 что значительно сокращает вычисления и сжимает изображение.
'''

import matplotlib.pyplot as plt
import numpy as np
import time

from PIL import Image

img = Image.open('img/amelieOrigin.png')
#.convert('L')
# plt.figure(figsize=(8, 8))
# plt.imshow(img)
# plt.show()


imgmat = np.array(list(img.getdata(band=0)), float)
imgmat.shape = (img.size[1], img.size[0])
imgmat = np.matrix(imgmat)
# plt.figure(figsize=(8, 8))
# plt.imshow(img)
# plt.show()


U, sigma, V = np.linalg.svd(imgmat)

print('input wm')
wm = 11100 
print('WM = ', str(wm)*11)
# WM =  11101110111011101110111011101110111011101110
# WM =  1110011100111001110011100111001110011100111001110011100

for i in range(11):
	print(sigma[i]) # U и V все меньше 1 
	sigma[i] = int(sigma[i]) + wm # если 11100, то уже видны изменения
	print(sigma[i])

for i in range(1, 602, 40):
    reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
    plt.imshow(reconstimg, cmap='gray')
    title = "n = %s" % i
    plt.title(title)
    plt.savefig(f'img/step-for-vectors-with-WM/{i}-vectors_of_the_singular_value_decomposition-{wm}.png') 
    #plt.show()

print('\ncheck')
for i in range(11):
	print(sigma[i]) # U и V все меньше 1 

"""
восстановленное изображение по первым n
  векторов разложения по сингулярным значениям (n
  указано в заголовке графика). Первые 50 векторов дают изображение, очень близкое к исходному, занимая при этом всего 50∗3900+50+50∗26003900∗2600≈3,2% от объема исходных данных.
  по сравнению с исходными данными.
"""

# for i in range(5, 51, 5):
#     reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
#     plt.imshow(reconstimg, cmap='gray')
#     title = "n = %s" % i
#     plt.title(title)
#     plt.savefig(f'img/{i}-vectors_of_the_singular_value_decomposition.png') 
#     #plt.show()

# for i in range(100, 151, 2):
#     reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
#     plt.imshow(reconstimg, cmap='gray')
#     title = "n = %s" % i
#     plt.title(title)
#     plt.savefig(f'img/step-for-vectors/{i}-vectors_of_the_singular_value_decomposition.png') 
#     #plt.show()

